#include"Camera.h"

Matrix Camera::LookAt(const Vec4f& eyePos, const Vec4f& lookat, const Vec4f& upAxis)
{
	//camera coord
	Vec4f lookDir = lookat;
	lookDir.Normalize();

	Vec4f rightDir = Vec4f::Cross(upAxis, lookDir);
	rightDir.Normalize();

	Vec4f upDir = Vec4f::Cross(lookDir, rightDir);
	upDir.Normalize();

	//camera transform
	Matrix m;
	m.mat[0][0] = rightDir.x; m.mat[0][1] = rightDir.y; m.mat[0][2] = rightDir.z; m.mat[0][3] = -eyePos.x;
	m.mat[1][0] = upDir.x; m.mat[1][1] = upDir.y; m.mat[1][2] = upDir.z; m.mat[1][3] = -eyePos.y;
	m.mat[2][0] = lookDir.x; m.mat[2][1] = lookDir.y; m.mat[2][2] = lookDir.z; m.mat[2][3] = -eyePos.z;
	m.mat[3][0] = 0; m.mat[3][1] = 0; m.mat[3][2] = 0; m.mat[3][3] = 1;
	viewmat = m;
	return viewmat;
}

//perspective transform
Matrix Camera::Perspective(float fov, float aspect, float nearPanel, float farPanel)
{
	float tanValue = tan(0.5f * fov * pi / 180);
	//float atValue = atan(fov*0.5);
	Matrix proj;
	proj.mat[0][0] = 1 / (tanValue * aspect);
	proj.mat[1][1] = tanValue;
	proj.mat[2][2] = (nearPanel + farPanel) / (nearPanel - farPanel);
	proj.mat[2][3] = 2 * nearPanel * farPanel / (nearPanel - farPanel);
	proj.mat[3][2] = -1;
	proj.mat[3][3] = 0;
	projmat = proj;
	//proj.Print();
	return proj;

	
}

Matrix Camera::Perspective(float l, float r, float n, float f, float t, float b)
{
	Matrix m;
	m.mat[0][0] = 2*n/(r-l); m.mat[0][1] = 0; m.mat[0][2]=(l+r)/(l-r); m.mat[0][3] = 0;
	m.mat[1][0] = 0; m.mat[1][1] = 2 * n / (t - b); m.mat[1][2] = (b+t)/(b-t); m.mat[1][3] = 0;
	m.mat[2][0] = 0; m.mat[2][1] = 0; m.mat[2][2] = (n+f)/(n-f); m.mat[2][3] =2*n*f/(f-n);
	m.mat[3][0] = 0; m.mat[3][1] = 0; m.mat[3][2] = 1; m.mat[3][3] = 0;
	projmat = m;
	return m;
}

//orthogonal transform
Matrix Camera::Orthographic(float l, float r, float n, float f, float t, float b)
{
	Matrix m;
	m.mat[0][0] = 2 / (r - l); m.mat[0][1] = 0; m.mat[0][2] = 0; m.mat[0][3] =-(r+l)/(r-l);
	m.mat[1][0] = 0; m.mat[1][1] = 2  / (t - b); m.mat[1][2] =0; m.mat[1][3] = -(t+b)/(t-b);
	m.mat[2][0] = 0; m.mat[2][1] = 0; m.mat[2][2] =2/ (n - f); m.mat[2][3] = -(n+f)/(n-f);
	m.mat[3][0] = 0; m.mat[3][1] = 0; m.mat[3][2] = 0; m.mat[3][3] = 1;
	projmat = m;
	return m;
}
